using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System.Security.Cryptography;
using System.Text;
using Lzfy_Refund_Service.Models;

namespace Lzfy_Refund_Service.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    [Authorize]
    public class FileController : ControllerBase
    {
        private readonly IWebHostEnvironment _environment;
        private readonly ILogger<FileController> _logger;
        private readonly FileStorageOptions _fileStorageOptions;

        public FileController(IWebHostEnvironment environment, ILogger<FileController> logger, IOptions<FileStorageOptions> fileStorageOptions)
        {
            _environment = environment;
            _logger = logger;
            _fileStorageOptions = fileStorageOptions.Value;
        }

        /// <summary>
        /// 上传患者附件图片
        /// </summary>
        /// <param name="file">上传的图片文件</param>
        /// <param name="patientId">患者ID</param>
        /// <returns>文件信息</returns>
        [HttpPost("upload")]
        public async Task<ActionResult> UploadFile(IFormFile file, [FromForm] string patientId)
        {
            try
            {
                // 验证患者ID
                if (string.IsNullOrWhiteSpace(patientId))
                {
                    return BadRequest(new { success = false, message = "患者ID不能为空" });
                }

                // 验证文件
                if (file == null || file.Length == 0)
                {
                    return BadRequest(new { success = false, message = "请选择要上传的图片文件" });
                }

                // 验证文件大小
                if (file.Length > _fileStorageOptions.MaxFileSize)
                {
                    var maxSizeMB = _fileStorageOptions.MaxFileSize / (1024 * 1024);
                    return BadRequest(new { success = false, message = $"文件大小不能超过{maxSizeMB}MB" });
                }

                // 验证文件扩展名（仅支持图片格式）
                var extension = Path.GetExtension(file.FileName).ToLowerInvariant();
                if (!_fileStorageOptions.AllowedImageExtensions.Contains(extension))
                {
                    var allowedFormats = string.Join(", ", _fileStorageOptions.AllowedImageExtensions.Select(ext => ext.TrimStart('.')));
                    return BadRequest(new { success = false, message = $"不支持的文件格式，仅支持图片格式：{allowedFormats}" });
                }

                // 生成文件ID
                var fileId = await GenerateFileId(file);

                // 创建上传目录（按日期和患者ID组织）
                var currentDate = DateTime.Now;
                var dateFolder = currentDate.ToString("yyyy-MM-dd");
                var uploadDir = Path.Combine(_environment.ContentRootPath, "upload", "images", dateFolder, patientId);
                if (!Directory.Exists(uploadDir))
                {
                    Directory.CreateDirectory(uploadDir);
                }

                // 生成文件名
                var fileName = $"{fileId}{extension}";
                var filePath = Path.Combine(uploadDir, fileName);

                // 保存文件
                using (var stream = new FileStream(filePath, FileMode.Create))
                {
                    await file.CopyToAsync(stream);
                }

                // 生成相对路径（相对于upload/images目录）
                var relativePath = Path.Combine(dateFolder, patientId, fileName).Replace("\\", "/");

                _logger.LogInformation($"文件上传成功: {fileName}, 文件ID: {fileId}");

                return Ok(new 
                { 
                    success = true, 
                    message = "文件上传成功",
                    data = new 
                    {
                        fileId = fileId,
                        fileName = file.FileName,
                        filePath = relativePath,
                        fileSize = file.Length,
                        uploadTime = DateTime.Now
                    }
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "文件上传失败");
                return StatusCode(500, new { success = false, message = "文件上传失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 上传Base64编码的文件
        /// </summary>
        /// <param name="request">包含Base64文件内容的请求</param>
        /// <returns>文件信息</returns>
        [HttpPost("upload-base64")]
        public async Task<ActionResult> UploadBase64File([FromBody] UploadBase64FileRequest request)
        {
            try
            {
                // 验证请求参数
                if (string.IsNullOrWhiteSpace(request.PatientId))
                {
                    return BadRequest(new { success = false, message = "患者ID不能为空" });
                }

                if (string.IsNullOrWhiteSpace(request.FileName))
                {
                    return BadRequest(new { success = false, message = "文件名不能为空" });
                }

                if (string.IsNullOrWhiteSpace(request.FileContent))
                {
                    return BadRequest(new { success = false, message = "文件内容不能为空" });
                }

                // 解码Base64文件内容
                byte[] fileBytes;
                try
                {
                    // 移除可能的数据URL前缀（如：data:image/png;base64,）
                    var base64Content = request.FileContent;
                    if (base64Content.Contains(","))
                    {
                        base64Content = base64Content.Split(',')[1];
                    }
                    fileBytes = Convert.FromBase64String(base64Content);
                }
                catch (FormatException)
                {
                    return BadRequest(new { success = false, message = "无效的Base64文件内容" });
                }

                // 验证文件大小
                if (fileBytes.Length > _fileStorageOptions.MaxFileSize)
                {
                    var maxSizeMB = _fileStorageOptions.MaxFileSize / (1024 * 1024);
                    return BadRequest(new { success = false, message = $"文件大小不能超过{maxSizeMB}MB" });
                }

                // 验证文件扩展名（仅支持图片格式）
                var extension = Path.GetExtension(request.FileName).ToLowerInvariant();
                if (!_fileStorageOptions.AllowedImageExtensions.Contains(extension))
                {
                    var allowedFormats = string.Join(", ", _fileStorageOptions.AllowedImageExtensions.Select(ext => ext.TrimStart('.')));
                    return BadRequest(new { success = false, message = $"不支持的文件格式，仅支持图片格式：{allowedFormats}" });
                }

                // 生成文件ID（基于文件内容）
                var fileId = await GenerateFileIdFromBytes(fileBytes);

                // 创建上传目录（按日期和患者ID组织）
                var currentDate = DateTime.Now;
                var dateFolder = currentDate.ToString("yyyy-MM-dd");
                var uploadDir = Path.Combine(_environment.ContentRootPath, "upload", "images", dateFolder, request.PatientId);
                if (!Directory.Exists(uploadDir))
                {
                    Directory.CreateDirectory(uploadDir);
                }

                // 生成文件名
                var fileName = $"{fileId}{extension}";
                var filePath = Path.Combine(uploadDir, fileName);

                // 保存文件
                await System.IO.File.WriteAllBytesAsync(filePath, fileBytes);

                // 生成相对路径（相对于upload/images目录）
                var relativePath = Path.Combine(dateFolder, request.PatientId, fileName).Replace("\\", "/");

                _logger.LogInformation($"Base64文件上传成功: {fileName}, 文件ID: {fileId}");

                return Ok(new 
                { 
                    success = true, 
                    message = "文件上传成功",
                    data = new 
                    {
                        fileId = fileId,
                        fileName = request.FileName,
                        filePath = relativePath,
                        fileSize = fileBytes.Length,
                        uploadTime = DateTime.Now
                    }
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Base64文件上传失败");
                return StatusCode(500, new { success = false, message = "文件上传失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 根据文件ID下载文件
        /// </summary>
        /// <param name="request">包含文件ID的请求</param>
        /// <returns>文件流</returns>
        [HttpPost("download")]
        public async Task<ActionResult> DownloadFile([FromBody] DownloadFileRequest request)
        {
            try
            {
                // 在应用部署路径下的upload/images目录及其子目录中搜索文件
                var uploadDir = Path.Combine(_environment.ContentRootPath, "upload", "images");
                if (!Directory.Exists(uploadDir))
                {
                    return NotFound(new { success = false, message = "文件存储目录不存在" });
                }

                // 递归搜索文件
                var files = Directory.GetFiles(uploadDir, $"{request.FileId}.*", SearchOption.AllDirectories);
                if (files.Length == 0)
                {
                    return NotFound(new { success = false, message = "文件不存在" });
                }

                var filePath = files[0]; // 取第一个匹配的文件
                var fileName = Path.GetFileName(filePath);
                var contentType = GetContentType(Path.GetExtension(fileName));

                var fileBytes = await System.IO.File.ReadAllBytesAsync(filePath);
                return File(fileBytes, contentType, fileName);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"下载文件失败: {request.FileId}");
                return StatusCode(500, new { success = false, message = "下载文件失败" });
            }
        }

        /// <summary>
        /// 根据相对路径获取文件
        /// </summary>
        /// <param name="request">包含文件相对路径的请求</param>
        /// <returns>文件流</returns>
        [HttpPost("get-by-path")]
        public async Task<ActionResult> GetFileByPath([FromBody] GetFileByPathRequest request)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(request.Path))
                {
                    return BadRequest(new { success = false, message = "文件路径不能为空" });
                }

                // 防止路径遍历攻击
                if (request.Path.Contains("..") || request.Path.Contains("~"))
                {
                    return BadRequest(new { success = false, message = "无效的文件路径" });
                }

                // 构建完整文件路径（基于应用部署路径下的upload/images目录）
                var fullPath = Path.Combine(_environment.ContentRootPath, "upload", "images", request.Path.Replace("/", "\\"));
                
                if (!System.IO.File.Exists(fullPath))
                {
                    return NotFound(new { success = false, message = "文件不存在" });
                }

                var fileName = Path.GetFileName(fullPath);
                var contentType = GetContentType(Path.GetExtension(fileName));

                var fileBytes = await System.IO.File.ReadAllBytesAsync(fullPath);
                return File(fileBytes, contentType, fileName);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取文件失败: {request.Path}");
                return StatusCode(500, new { success = false, message = "获取文件失败" });
            }
        }

        /// <summary>
        /// 根据文件ID下载Base64编码的文件
        /// </summary>
        /// <param name="request">包含文件ID的请求</param>
        /// <returns>Base64编码的文件内容</returns>
        [HttpPost("download-base64")]
        public async Task<ActionResult> DownloadBase64File([FromBody] DownloadBase64FileRequest request)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(request.FileId))
                {
                    return BadRequest(new { success = false, message = "文件ID不能为空" });
                }

                // 在应用部署路径下的upload/images目录及其子目录中搜索文件
                var uploadDir = Path.Combine(_environment.ContentRootPath, "upload", "images");
                if (!Directory.Exists(uploadDir))
                {
                    return NotFound(new { success = false, message = "文件存储目录不存在" });
                }

                // 递归搜索文件
                var files = Directory.GetFiles(uploadDir, $"{request.FileId}.*", SearchOption.AllDirectories);
                if (files.Length == 0)
                {
                    return NotFound(new { success = false, message = "文件不存在" });
                }

                var filePath = files[0]; // 取第一个匹配的文件
                var fileName = Path.GetFileName(filePath);
                var extension = Path.GetExtension(fileName);
                var contentType = GetContentType(extension);

                var fileBytes = await System.IO.File.ReadAllBytesAsync(filePath);
                var base64Content = Convert.ToBase64String(fileBytes);

                _logger.LogInformation($"Base64文件下载成功: {fileName}, 文件ID: {request.FileId}");

                return Ok(new 
                { 
                    success = true, 
                    message = "文件获取成功",
                    data = new 
                    {
                        fileId = request.FileId,
                        fileName = fileName,
                        contentType = contentType,
                        fileSize = fileBytes.Length,
                        fileContent = base64Content
                    }
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Base64文件下载失败: {request.FileId}");
                return StatusCode(500, new { success = false, message = "下载文件失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 根据相对路径获取Base64编码的文件
        /// </summary>
        /// <param name="request">包含文件相对路径的请求</param>
        /// <returns>Base64编码的文件内容</returns>
        [HttpPost("get-base64-by-path")]
        public async Task<ActionResult> GetBase64FileByPath([FromBody] GetBase64FileByPathRequest request)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(request.Path))
                {
                    return BadRequest(new { success = false, message = "文件路径不能为空" });
                }

                // 防止路径遍历攻击
                if (request.Path.Contains("..") || request.Path.Contains("~"))
                {
                    return BadRequest(new { success = false, message = "无效的文件路径" });
                }

                // 构建完整文件路径（基于应用部署路径下的upload/images目录）
                var fullPath = Path.Combine(_environment.ContentRootPath, "upload", "images", request.Path.Replace("/", "\\"));
                
                if (!System.IO.File.Exists(fullPath))
                {
                    return NotFound(new { success = false, message = "文件不存在" });
                }

                var fileName = Path.GetFileName(fullPath);
                var extension = Path.GetExtension(fileName);
                var contentType = GetContentType(extension);

                var fileBytes = await System.IO.File.ReadAllBytesAsync(fullPath);
                var base64Content = Convert.ToBase64String(fileBytes);

                _logger.LogInformation($"Base64文件获取成功: {fileName}, 路径: {request.Path}");

                return Ok(new 
                { 
                    success = true, 
                    message = "文件获取成功",
                    data = new 
                    {
                        fileName = fileName,
                        filePath = request.Path,
                        contentType = contentType,
                        fileSize = fileBytes.Length,
                        fileContent = base64Content
                    }
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Base64文件获取失败: {request.Path}");
                return StatusCode(500, new { success = false, message = "获取文件失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 生成文件ID
        /// </summary>
        /// <param name="file">文件</param>
        /// <returns>文件ID</returns>
        private async Task<string> GenerateFileId(IFormFile file)
        {
            // 使用文件内容生成哈希
            using var md5 = MD5.Create();
            using var stream = file.OpenReadStream();
            var hashBytes = await Task.Run(() => md5.ComputeHash(stream));
            var hash = BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
            
            // 组合时间戳和哈希生成唯一ID
            var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
            return $"{timestamp}_{hash.Substring(0, 8)}";
        }

        /// <summary>
        /// 根据字节数组生成文件ID
        /// </summary>
        /// <param name="fileBytes">文件字节数组</param>
        /// <returns>文件ID</returns>
        private async Task<string> GenerateFileIdFromBytes(byte[] fileBytes)
        {
            // 使用文件内容生成哈希
            using var md5 = MD5.Create();
            var hashBytes = await Task.Run(() => md5.ComputeHash(fileBytes));
            var hash = BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
            
            // 组合时间戳和哈希生成唯一ID
            var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
            return $"{timestamp}_{hash.Substring(0, 8)}";
        }

        /// <summary>
        /// 获取文件的Content-Type
        /// </summary>
        /// <param name="extension">文件扩展名</param>
        /// <returns>Content-Type</returns>
        private string GetContentType(string extension)
        {
            return extension.ToLowerInvariant() switch
            {
                ".jpg" or ".jpeg" => "image/jpeg",
                ".png" => "image/png",
                ".pdf" => "application/pdf",
                ".doc" => "application/msword",
                ".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                _ => "application/octet-stream"
            };
        }
    }
}